package gatperdut.chato.core.item.inventory;

import gatperdut.chato.constants.CSConstantsInventory;
import gatperdut.chato.constants.CSConstantsString;
import gatperdut.chato.core.ChatoServer;
import gatperdut.chato.core.characters.BaseController;
import gatperdut.chato.core.interpreter.grammar.comminfo.indexedword.IndexedWord;
import gatperdut.chato.core.item.ItemController;
import gatperdut.chato.model.Chato.Constant.WearLoc;
import gatperdut.chato.model.Chato.Item.EntityInventory;
import gatperdut.chato.model.Chato.Item.EntityInventorySlot;
import gatperdut.chato.model.Chato.Item.Item;

import java.util.List;

public class EntityInventoryController extends InventoryController {

    private final SlotsController slotsController;

    private final BaseController baseController;

    public EntityInventoryController( ChatoServer chatoServer, EntityInventory entityInventory, BaseController baseController ) {
        super( chatoServer, entityInventory );

        this.baseController = baseController;

        slotsController = new SlotsController( getChatoServer(), entityInventory.getSlots() );
        loadItems( ( (EntityInventory) getInventory() ).getSlots() );
    }

    private void loadItems( List<EntityInventorySlot> slots ) {
        ItemController ic;
        Item i;
        for ( EntityInventorySlot eis : slots ) {
            i = eis.getItem();
            if ( eis.getItem() != null ) {
                ic = new ItemController( getChatoServer(), i );
                putInInventory( eis.getWearLoc(), ic );
                getChatoServer().getItemHandler().getItemCDOIDToController().put( i.cdoID().toURIFragment(), ic );
            }
        }
    }

    public ItemController getHeldItemController( IndexedWord iw ) {
        ItemController r = getRHandItemController();
        if ( r != null && r.getKeywordsController().matchesKeyword( iw.getWord() ) ) {
            return r;
        }

        ItemController l = getLHandItemController();
        if ( l != null && l.getKeywordsController().matchesKeyword( iw.getWord() ) ) {
            return l;
        }

        return null;
    }

    @Override
    public void unloadItems() {
        super.unloadItems();
        getSlotsController().clearReferences();
    }

    public void putInInventory( WearLoc wearLoc, ItemController ic ) {
        ic.setContainerController( this );
        getItemControllers().add( ic );
        getInventory().getItems().add( ic.getItem() );
        getSlotsController().setItem( wearLoc, ic );
    }

    @Override
    public void takeFromInventory( ItemController ic ) {
        super.takeFromInventory( ic );
        getSlotsController().removeItem( ic );
    }

    public void take( ItemController ic ) {
        putInInventory( getFreeHandWearLoc(), ic );
    }

    public ItemController getRHandItemController() {
        return getSlotsController().getWearLocToItemController().get( WearLoc.RHAND );
    }

    public ItemController getLHandItemController() {
        return getSlotsController().getWearLocToItemController().get( WearLoc.LHAND );
    }

    public boolean hasOneFreeHand() {
        return getSlotsController().getItemController( WearLoc.LHAND ) == null || getSlotsController().getItemController( WearLoc.RHAND ) == null;
    }

    public WearLoc getFreeHandWearLoc() {
        if ( getSlotsController().getItemController( WearLoc.RHAND ) == null ) {
            return WearLoc.RHAND;
        }
        else if ( getSlotsController().getItemController( WearLoc.LHAND ) == null ) {
            return WearLoc.LHAND;
        }

        return null;
    }

    @Override
    public EntityInventory getInventory() {
        return (EntityInventory) super.getInventory();
    }

    @Override
    public String listContentsShortDescription( boolean showDrinkableContents ) {
        StringBuilder contents = new StringBuilder( "" );
        boolean firstListed = false;
        ItemController ic;
        for ( EntityInventorySlot eic : getInventory().getSlots() ) {
            if ( eic.getItem() != null ) {
                if ( !firstListed ) {
                    firstListed = true;
                }
                else {
                    contents.append( CSConstantsString.NEWLINE );
                }
                String wearLocName = CSConstantsInventory.getWearLocInvName( eic.getWearLoc() );
                ic = getSlotsController().getWearLocToItemController().get( eic.getWearLoc() );
                contents.append( "<" + wearLocName + "> - " + ic.getShortDesc( showDrinkableContents ) );
            }
        }
        return contents.toString();

    }

    public SlotsController getSlotsController() {
        return slotsController;
    }

    public boolean isWearLocFree( WearLoc wearLoc ) {
        return getSlotsController().isWearLocFree( wearLoc );
    }

    public BaseController getBaseController() {
        return baseController;
    }

}
